
import java.io.*;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLEditorKit;


public class Spider {

    protected Collection URLmajuError = new ArrayList(3);
    protected Collection URLcakaju = new ArrayList(3);
    protected Collection URLnaSpracovanie = new ArrayList(3);
    protected SpiderReport report;
    protected boolean koniec = false;

    public Spider(SpiderReport report) {
        this.report = report;
    }

    public Collection getURLmajuError() {
        return URLmajuError;
    }

    public Collection getURLcakaju() {
        return URLcakaju;
    }

    public Collection getURLnaSpracovanie() {
        return URLnaSpracovanie;
    }

    public void clear() {
        getURLmajuError().clear();
        getURLcakaju().clear();
        getURLnaSpracovanie().clear();
    }

    public void cancel() {
        koniec = true;
    }

    public void addURL(URL url) {
        if (getURLcakaju().contains(url)) {
            return;
        }
        if (getURLmajuError().contains(url)) {
            return;
        }
        if (getURLnaSpracovanie().contains(url)) {
            return;
        }
        log("Pridáva sa do zoznamu: " + url);
        getURLcakaju().add(url);
    }

    public void spracujURL(URL url) {
        try {
            log("Spracuváva sa: " + url);

            URLConnection connection = url.openConnection();
            if ((connection.getContentType() != null) && !connection.getContentType().toLowerCase().startsWith("text/")) {
                getURLcakaju().remove(url);
                getURLnaSpracovanie().add(url);
                log("Nespracuváva sa lebo obsah je: "
                        + connection.getContentType());
                return;
            }

            InputStream is = connection.getInputStream();
            Reader r = new InputStreamReader(is);
            HTMLEditorKit.Parser parse = new HTMLAnalyzator().getParser();
            parse.parse(r, new Parser(url), true);
        } catch (IOException e) {

            getURLcakaju().remove(url);
            getURLmajuError().add(url);
            log("Error: " + url + " > " + e.toString());
            report.spiderURLError(url);
            return;
        }
        //kompletne URL
        getURLcakaju().remove(url);
        getURLnaSpracovanie().add(url);
        log("Kompletne: " + url);

    }
    //start spidera
    public void begin() {
        koniec = false;
        while (!getURLcakaju().isEmpty() && !koniec) {
            Object list[] = getURLcakaju().toArray();
            for (int i = 0; (i < list.length) && !koniec; i++) {
                spracujURL((URL) list[i]);
            }
        }
    }

    protected class Parser extends HTMLEditorKit.ParserCallback {

        protected URL base;

        public Parser(URL base) {
            this.base = base;
        }

        @Override
        public void handleText(char[] data, int pos) {
//            StringBuilder sb = new StringBuilder();
//            
//            for (int i = 0; i < data.length; i++) {
//                sb.append(data[i]);
//            }
//            String s = sb.toString();
//            if(s.contains(retazec)){
//                //doplniť pre hľadanie reťazcov
//            }
//            System.out.println(data.toString());
            super.handleText(data, pos);
        }

        @Override
        public void handleSimpleTag(HTML.Tag t, MutableAttributeSet a, int pos) {

            String href = (String) a.getAttribute(HTML.Attribute.HREF);
            if ((href == null) && (t == HTML.Tag.FRAME)) {
                href = (String) a.getAttribute(HTML.Attribute.SRC);
            }

            if (href == null) {
                return;
            }

            int i = href.indexOf('#');
            if (i != -1) {
                href = href.substring(0, i);
            }

            if (href.toLowerCase().startsWith("mailto:")) {
                report.spiderNasielEMail(href);
                return;
            }
            handleLink(base, href);
        }

        @Override
        public void handleStartTag(HTML.Tag t, MutableAttributeSet a, int pos) {
            handleSimpleTag(t, a, pos);

        }

        protected void handleLink(URL base, String str) {
            try {
                URL url = new URL(base, str);
                if (report.spiderNasielURL(base, url)) {
                    addURL(url);
                }
            } catch (MalformedURLException e) {
                log("Nesprávne URL: " + str);
            }
        }
    }

    public void log(String s) {
        //System.out.println(new Date() + ": " + s);
        report.spiderLog(s);
    }
}